######################################################################
# Time-stamp: <05/08/09 14:23:57 ostolop>
#
# Package: EP::Common::DBI::Dataset
#
# DBI object mapping to the *dataset* table
######################################################################
package EP::Common::DBI::Dataset;

use strict;
use base qw ( EP::Common::DBI );

use File::Temp;
use File::Spec;

use EP::Core::Dataset::Data::Factory;
use Class::DBI::AbstractSearch;

EP::Common::DBI::Dataset->table ( 'ep_dataset' );
EP::Common::DBI::Dataset->sequence ( 'ep_dataset_seq' );

EP::Common::DBI::Dataset->columns ( Primary   => qw ( id ) );
EP::Common::DBI::Dataset->columns ( Essential => qw ( name type filename folder owner ep_session ) );
EP::Common::DBI::Dataset->columns ( Others    => qw ( description species group_write group_read other_read created last_used ) );

EP::Common::DBI::Dataset->add_trigger ( before_create => \&_before_create );

EP::Common::DBI::Dataset->has_a ( folder   => 'EP::Common::DBI::Folder' );
EP::Common::DBI::Dataset->has_a ( owner    => 'EP::Common::DBI::User'   );
EP::Common::DBI::Dataset->has_a ( ep_session  => 'EP::Common::DBI::Session' );

EP::Common::DBI::Dataset->has_many ( metadata => 'EP::Common::DBI::Dataset_Metadata' );

# sub: data
#   Lazy-loading routine to retrieve the data object associated with the dataset and associate the object with the
#   dataset. Data will only be read in and instantiated when this function is called. If the data has been read in once,
#   it will be returned without-rereading, unless explicitly forced (see parameters). Note: on the GUI server, this will
#   result in errors (TODO handling).
# parameters:
#   Can /optionally/ take one parameter, an object reference, in which case will set the data object to that. The passed
#   reference should be to an instance of a subclass of <EP::Core::Dataset::Data>.
# returns:
#   The local instance of EP::Common::DBI::Dataset::Data::*type*, where *type* depends on the type of the dataset.
sub data {
  my $self = shift;

  # set up the data if it was passed as an argument
  if ( ref ( $_[0] ) =~ "EP::Core::Dataset::Data" ) {
    $self->{data} = $_[0];
    $self->{data}->{owner} = $self;
  }

  $self->{data} = EP::Core::Dataset::Data::Factory->create_dataset_data ( data_type => $self->type, owner_dataset => $self )
    unless $self->{data};

  die "Failed to lazy-instantiate the data for the dataset " . $self->dataset_name . " (" . $self->dataset_id . " )"
      unless $self->{data};

  return $self->{data};
}

# sub: _before_create
#  Special trigger to aid in creating datasets, responsible for generating a filename for the dataset-related data.
sub _before_create {
  my $self = shift;

  $self->autoupdate(0);

  $self->folder ( retrieve EP::Common::DBI::Folder ( $self->folder ) ) if not ref ( $self->folder ) eq "EP::Common::DBI::Folder";
  die "Couldn't find folder for new dataset!" if not $self->folder->location;

  my $new_filename = mktemp ( File::Spec->catfile ( $EP::Config::h->{EPNG_USRDATA_PATH}, $self->folder->location, "data.$$.XXXXX" ) );
  my $nf = (File::Spec->splitpath ( $new_filename ))[2];
  $self->filename ( $nf );

  $self->autoupdate(1);
}

1;
